package com.cvpoc.spring.common.controller.langue;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import com.cvpoc.dto.CollaborateurLangueDTO;
import com.cvpoc.dto.LangueDTO;
import com.cvpoc.exception.BusinessException;
import com.cvpoc.service.LangueService;
import com.cvpoc.spring.common.form.langue.LangueCollaborateurForm;
import com.cvpoc.spring.common.validator.langue.LangueValidator;
import com.cvpoc.struts.form.LangueForm;

public class LangueCollaborateurController extends MultiActionController {

	BindingResult errors;	
	
	public BindingResult getErrors() {
		return errors;
	}

	public void setErrors(BindingResult errors) {
		this.errors = errors;
	}
	
	@Override
	protected void bind(HttpServletRequest request, Object command) throws Exception {
		ServletRequestDataBinder binder = createBinder(request, command);
		binder.bind(request);
		errors = binder.getBindingResult();
	}	
	
	/**
	 * 
	 * Instantiation de la variable logger destinée à 
	 * recevoir les methodes du gestionnaire de log
	 * 
	 */
    protected final Log logger = LogFactory.getLog(getClass());
    
    /**
     * 
     * Id du collaborateur
     * 
     */
    
    private static final int ID_COL = 1;
    
    /**
     * 
     * Instantiation de la classe contenant les templates 
     * 
     */
    protected String templatefoldercommon;

    protected static final String REDIRECT_ROOT_LANGUE = "redirect:afficherliste.htm";
    
	/**
     * 
     * Affichage de la liste des langues remplis par l'utilisateur.
     * Si l'utilisateur n'en dispose pas, une notification lui est affiché
     * à l'écran.
     * 
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     * @throws BusinessException
     * 
     */
    public ModelAndView afficherlisteLangue(HttpServletRequest request,
    		HttpServletResponse response)
            throws Exception  {
    		try {
    			LangueService langueService = (LangueService) getWebApplicationContext().getBean("langueService");
    			List<CollaborateurLangueDTO> languesDTO = langueService.rechercherListLanguesByIdCollaborateur(ID_COL);
    			request.setAttribute("langues", languesDTO);
    			logger.info("afficher la liste de langue");
    			return new ModelAndView(templatefoldercommon + "afficherListeLangue");
    		}catch (BusinessException e) {
    			return new ModelAndView(templatefoldercommon + "afficherListeLangue");
    		}
    }
    
    /**
     * Affichage du formulaire permetant d'ajouter une langue
     * 
     * @param request
     * @param response
     * @return
     * @throws Exception
     * 
     */
    public ModelAndView ajouterLangue(HttpServletRequest request,
    		HttpServletResponse response)
            throws Exception  {
    	
    	LangueCollaborateurForm langue = new LangueCollaborateurForm();
    	
    	LangueService langueService = (LangueService) getWebApplicationContext().getBean("langueService");
		List<LangueDTO> listeLangue = langueService.rechercherListeLangue();
		
		Map referenceData = new HashMap();
		Map<String,String> langueList = new LinkedHashMap<String,String>();
		
		if(listeLangue.size() > 0 ) {
			for(LangueDTO langueDTO : listeLangue) {
				langueList.put(String.valueOf(langueDTO.getId()),langueDTO.getLibelle());
			}
		}
		
		langue.setLangueList(langueList);
		
		request.setAttribute("urlPostAction", "save");
    	
    	return new ModelAndView(templatefoldercommon + "formulaireLangue",
    			"langue", langue);
    }
    
    /**
     * Enregistrerment de la langue
     * 
     * @param request
     * @param response
     * @param langue
     * @return
     * @throws Exception
     * 
     */
    
    public ModelAndView saveLangue(HttpServletRequest request,
    		HttpServletResponse response, LangueCollaborateurForm langue)
            throws Exception  {
    	
    		validate(langue);
    		
    		if(errors.hasErrors()) {
    			saveError(request,errors.getFieldError().getCode());
    			logger.info("Error Handling : " + errors.getFieldError().getCode());
    			return new ModelAndView(templatefoldercommon + "faillureLangue","command",new LangueCollaborateurForm()); 
    		} else {
    			//sauvegarde
    			try {
    				LangueService langueService = (LangueService)getWebApplicationContext().getBean("langueService");

    		    	LangueDTO langueDTO			= langueService.rechercherLangueBydIdLangue(Integer.parseInt(langue.getLibelle()));
    		    	
    		    	CollaborateurLangueDTO collaborateurLangueDTO = setCollaborateurLangueDTO(langue, langueDTO);
    		
    		    	langueService.ajouterCollaborateurLangue(collaborateurLangueDTO);
    		    	return new ModelAndView(REDIRECT_ROOT_LANGUE);
    			}catch (BusinessException e) {
    				return new ModelAndView(templatefoldercommon + "faillureLangue");
    			}
    		}
    }
    
	/**
	 * 
	 * @param langue
	 * @param langueDTO
	 * @return
	 * 
	 */
	
	private CollaborateurLangueDTO setCollaborateurLangueDTO(
			LangueCollaborateurForm langue, LangueDTO langueDTO) {
		CollaborateurLangueDTO collaborateurLangueDTO = new CollaborateurLangueDTO();
    	
    	collaborateurLangueDTO.setId_collaborateur(ID_COL);
    	collaborateurLangueDTO.setLangue(langueDTO);
    	collaborateurLangueDTO.setNiveau(langue.getNiveau());
    	collaborateurLangueDTO.setPratique(langue.getPratique());
    	collaborateurLangueDTO.setCommentaire(langue.getCommentaire());
		return collaborateurLangueDTO;
	}	    
    
    /**
     * 
     * Validation des données entré par l'utilisateur
     * 
     * @param command
     * 
     */
    
	public void validate(Object command) {
		Validator[] validators = getValidators();
		if(validators != null) {
			for(int index = 0; index < validators.length; index++) {
				Validator validator = validators[index];
				if(validator instanceof LangueValidator) {
					if(((LangueValidator)validator).supports(command.getClass())) {
						ValidationUtils.invokeValidator(validators[index], command, errors);
					} else if (validator.supports(command.getClass())) {
						ValidationUtils.invokeValidator(validators[index], command, errors);
					}
				}
			}
		}
	}
	
	/**
	 * 
	 * Erreur durant la sauvegarde
	 * 
	 * @param request
	 * @param msg
	 * 
	 */
	
	public void saveError(HttpServletRequest request, String msg) {
		List<String> errors = (List) request.getAttribute("errors");
		if(errors == null) {
			errors = new ArrayList<String>();
		}
		errors.add(msg);
		request.setAttribute("errors",errors);
	}
	
	/**
	 * 
	 * Supprimer une langue.
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 * 
	 */
	
	public ModelAndView supprimerLangue(HttpServletRequest request,
    		HttpServletResponse response)
            throws Exception  {
			
		logger.info(request.getParameter("idlangue"));
		
		try {
			LangueService langueService = (LangueService) getWebApplicationContext()
					.getBean("langueService");
			
			if(Integer.valueOf(request.getParameter("idlangue")) == 0) {
				return new ModelAndView(REDIRECT_ROOT_LANGUE);
			} 	
			
			CollaborateurLangueDTO collaborateurLangueDTO = langueService.rechercherLangueBydIdCollaborateur(Integer.valueOf(request.getParameter("idlangue")), ID_COL);
			
			if(collaborateurLangueDTO.getId_collaborateur() == 0) {
				// injecter une notification
				return new ModelAndView(REDIRECT_ROOT_LANGUE);
			}
			
			langueService.supprimerCollaborateurLangue(collaborateurLangueDTO);
			return new ModelAndView(REDIRECT_ROOT_LANGUE);
		}catch (BusinessException e) {
			// injecter une notification
			return new ModelAndView(REDIRECT_ROOT_LANGUE);
		}
	}
	
	/**
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 * 
	 */
	
	public ModelAndView editerLangue(HttpServletRequest request,
    		HttpServletResponse response)
            throws Exception  {
		
    	LangueCollaborateurForm langue = new LangueCollaborateurForm();
    	
    	LangueService langueService = (LangueService) getWebApplicationContext().getBean("langueService");
		List<LangueDTO> listeLangue = langueService.rechercherListeLangue();
		
		Map referenceData = new HashMap();
		Map<String,String> langueList = new LinkedHashMap<String,String>();
		
		if(listeLangue.size() > 0 ) {
			for(LangueDTO langueDTO : listeLangue) {
				langueList.put(String.valueOf(langueDTO.getId()),langueDTO.getLibelle());
			}

			langue.setLangueList(langueList);
			
			CollaborateurLangueDTO collaborateurLangueDTO = langueService.rechercherLangueBydIdCollaborateur(
					Integer.valueOf(request.getParameter("idlangue")), ID_COL);
			
			// on set les champs qui seront affichés ou posté.
			langue.setCommentaire(collaborateurLangueDTO.getCommentaire());
			langue.setNiveau(collaborateurLangueDTO.getNiveau());
			langue.setPratique(collaborateurLangueDTO.getPratique());	
			
			// on récupère la valeur en provenance de la base et on la définit en valeur par défaut.
			langue.setLibelle(Integer.toString(collaborateurLangueDTO.getLangue().getId()));
			
			request.setAttribute("urlPostAction", "actualiser");
			
			return new ModelAndView(templatefoldercommon + "formulaireLangue",
	    			"langue", langue);
		} else {
			return new ModelAndView(REDIRECT_ROOT_LANGUE);
		}
	}
	
	/**
	 * 
	 * @param request
	 * @param response
	 * @param langue
	 * @return
	 * @throws Exception
	 * 
	 */
	public ModelAndView actualiserLangue(HttpServletRequest request,
    		HttpServletResponse response, LangueCollaborateurForm langue)
            throws Exception  {
		
		validate(langue);
		
		if(errors.hasErrors()) {
			saveError(request,errors.getFieldError().getCode());
			logger.info("Error Handling : " + errors.getFieldError().getCode());
			return new ModelAndView(templatefoldercommon + "faillureLangue","command",new LangueCollaborateurForm()); 
		} else {
			try {
				LangueService langueService = (LangueService) getWebApplicationContext()
						.getBean("langueService");
				
				ArrayList langueList 	= new ArrayList();
		    	LangueDTO langueDTO		= langueService.rechercherLangueBydIdLangue(Integer.parseInt(langue.getLibelle()));
		    	
		    	CollaborateurLangueDTO collaborateurLangueDTO = setCollaborateurLangueDTO(langue, langueDTO);;
				langueService.modifierCollaborateurLangue(collaborateurLangueDTO);
				return new ModelAndView(REDIRECT_ROOT_LANGUE);
			}catch (BusinessException e) {
				return new ModelAndView(REDIRECT_ROOT_LANGUE);
			}
		}
	}

    /**
     * 
     * Récupération du nom du dossier concernant ce controlleur depuis
     * templatefolder.properties et application de la mutation.
     * 
     * @param templatefoldercommon
     * 
     */
	public void setTemplatefoldercommon(String templatefoldercommon) {
		this.templatefoldercommon = templatefoldercommon;
	}
	
}
